package com.niiwoo.civet.account.service.local;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.rpc.RpcContext;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.niiwoo.activity.stage.dto.request.prize.ActivityNotifyRequestDTO;
import com.niiwoo.activity.stage.dto.response.prize.SendOrderDetailRespDTO;
import com.niiwoo.activity.stage.enums.prize.SendPrizeDetailProjectTypeEnum;
import com.niiwoo.activity.stage.enums.prize.SendPrizeStatusEnum;
import com.niiwoo.activity.stage.enums.prize.UserPrizeFromTypeEnum;
import com.niiwoo.activity.stage.service.prize.ActivityNotifyDubboService;
import com.niiwoo.activity.stage.service.prize.ActivityPrizeDubboService;
import com.niiwoo.civet.account.constant.MQConstant;
import com.niiwoo.civet.account.dao.entity.AccountBase;
import com.niiwoo.civet.account.dao.entity.ActivityOrder;
import com.niiwoo.civet.account.dao.mapper.AccountBaseMapperExt;
import com.niiwoo.civet.account.dao.mapper.ActivityOrderMapper;
import com.niiwoo.civet.account.dto.bill.AddBillAndChangeBalanceDTO;
import com.niiwoo.civet.account.dto.bill.AddBillDetailDTO;
import com.niiwoo.civet.account.dto.common.MoneyTotalDTO;
import com.niiwoo.civet.account.dto.request.MarketingDubboRequestDTO;
import com.niiwoo.civet.account.dto.request.ReissueOrderAuditMqReqDTO;
import com.niiwoo.civet.account.dto.response.ActivityOrderRespDTO;
import com.niiwoo.civet.account.enums.*;
import com.niiwoo.civet.account.service.local.bill.BillFacade;
import com.niiwoo.civet.base.enums.BorrowProjectTypeEnum;
import com.niiwoo.civet.base.enums.ChannelCodeEnum;
import com.niiwoo.civet.trade.constant.PlatformConstant;
import com.niiwoo.civet.trade.dto.common.ProjectDTO;
import com.niiwoo.civet.trade.service.project.ProjectDubboService;
import com.niiwoo.tripod.lanmao.component.LanMaoDirectService;
import com.niiwoo.tripod.lanmao.component.LanMaoSequence;
import com.niiwoo.tripod.lanmao.enums.*;
import com.niiwoo.tripod.lanmao.request.AsyncTransactionRequest;
import com.niiwoo.tripod.lanmao.request.QueryTransactionRequest;
import com.niiwoo.tripod.lanmao.response.AsyncTransactionResponse;
import com.niiwoo.tripod.lanmao.response.QueryTransactionResponse;
import com.niiwoo.tripod.provider.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

/**
 * @Description
 * @Author zq
 * @Date 2017/12/2
 */
@Service
@Slf4j
public class MarketingLocalService {


    @Autowired
    LanMaoDirectService lanMaoDirectService;
    @Autowired
    ActivityOrderMapper activityOrderMapper;
    @Autowired
    AccountBaseMapperExt accountBaseMapperExt;
    @Autowired
    private LanMaoSequence lanMaoSequence;
    @Autowired
    BillFacade billFacade;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    MoneyTotalLocalService moneyTotalLocalService;
    @Autowired
    private AccountService accountService;

    @Reference(version = "1.0.0")
    ActivityPrizeDubboService activityPrizeDubboService;
    @Reference(version = "1.0.0")
    ActivityNotifyDubboService activityNotifyDubboService;
    @Reference(version = "1.0.0")
    private ProjectDubboService projectDubboService;


    @Transactional
    public ActivityOrder addSendCashOrder(MarketingDubboRequestDTO requestDTO) {
        ActivityOrder activityOrder = new ActivityOrder();
        activityOrder.setId(requestDTO.getOrderNo());
        if (StringUtils.isNotBlank(requestDTO.getRequestNo())) {
            activityOrder.setRequestNo(requestDTO.getRequestNo());
        } else {
            activityOrder.setRequestNo(lanMaoSequence.getRequestNo());
        }
        activityOrder.setUserId(requestDTO.getUserId());
        activityOrder.setAccountRole(requestDTO.getUserRoleEnum().getValue());
        activityOrder.setAmount(requestDTO.getAmount());
        if (StringUtils.isNotBlank(requestDTO.getBatchOrderNo())) {
            activityOrder.setBatchOrderNo(requestDTO.getBatchOrderNo());
        } else {
            activityOrder.setBatchOrderNo(lanMaoSequence.getBatchNo());
        }
        activityOrder.setPrizetypeid(requestDTO.getPrizeTypeIdEnum().getPrizeType());
        activityOrder.setAccountNo(requestDTO.getAccountNo());
        activityOrder.setExtendType(requestDTO.getExtendTypeEnum().getExtendType());
        activityOrder.setSourceFrom(requestDTO.getSourceTypeEnum().getSourceFrom());
        activityOrderMapper.insertSelective(activityOrder);
        log.info("添加现金红包发送订单信息:{}", requestDTO.getRequestNo());
        return activityOrder;
    }

    @Transactional
    public ActivityOrder getActivityOrderByRequestNo(String requestNo) {
        ActivityOrder order = activityOrderMapper.selectByRequestNoForUpdate(requestNo);
        return order;
    }

    public boolean asyncSendTransaction(String requestNo, UserRoleEnum userRoleEnum) throws BizException, ExecutionException, InterruptedException {
        log.info("开始请求银行存管发送现金红包---start---{}", requestNo);
        AsyncTransactionRequest request = getSlefProxy().getAsyncTransactionRequest(requestNo, userRoleEnum);
        AsyncTransactionResponse response = this.asyncTransaction(request);
        if (response == null) {
            log.error("存管系统批量交易请求无响应");
            return false;
        }
        if (ResponseCodeEnum.FAILURE.getValue().equals(response.getCode())
                || ResponseStatusEnum.INIT.getValue().equals(response.getStatus())) {
            //修改还款订单为失败,中止流程
            throw new BizException("ACC10022");
        }
        log.info("开始请求银行存管发送现金红包---end---");
        return true;
    }

    @Transactional
    public AsyncTransactionRequest getAsyncTransactionRequest(String requestNo, UserRoleEnum userRoleEnum) {
        ActivityOrder activityOrder = activityOrderMapper.selectByRequestNoForUpdate(requestNo);
        AsyncTransactionRequest request = new AsyncTransactionRequest();
        AsyncTransactionRequest.BizDetail bizDetail = new AsyncTransactionRequest.BizDetail();
        bizDetail.setTradeType(TransactionTypeEnum.MARKETING);
        bizDetail.setRequestNo(activityOrder.getRequestNo());
        AsyncTransactionRequest.BizDetail.BusinessDetail businessDetail = new AsyncTransactionRequest.BizDetail.BusinessDetail();
        businessDetail.setBizType(BusinessTypeEnum.MARKETING);
        businessDetail.setSourcePlatformUserNo(PlateformAccountEnum.SYS_GENERATE_002.name());

        if(StringUtils.isNotBlank(activityOrder.getAccountNo())) {
            businessDetail.setTargetPlatformUserNo(activityOrder.getAccountNo());
        }else {
            AccountBase accountBase = accountService.getNiiwooAccount(activityOrder.getUserId(), userRoleEnum);
            businessDetail.setTargetPlatformUserNo(accountBase.getAccountNo());
        }
        businessDetail.setAmount(activityOrder.getAmount());
        List<AsyncTransactionRequest.BizDetail.BusinessDetail> detailList = new ArrayList<>();
        detailList.add(businessDetail);
        bizDetail.setDetails(detailList);
        List<AsyncTransactionRequest.BizDetail> bizDetailList = new ArrayList<>();
        bizDetailList.add(bizDetail);
        request.setBizDetails(bizDetailList);
        request.setBatchNo(activityOrder.getBatchOrderNo());
        log.info("拼装存管请求参数：{}", JSON.toJSONString(request));
        return request;
    }

    public AsyncTransactionResponse asyncTransaction(AsyncTransactionRequest request) throws ExecutionException, InterruptedException {
        log.info("Marketing调用存管请求参数:{}" , JSON.toJSONString(request));
        CompletableFuture<AsyncTransactionResponse> future = lanMaoDirectService.asyncTransaction(request);
        AsyncTransactionResponse response = null;
        try {
            response = future.get();
        } catch (Exception e) {
            log.error("调用存管发送错误：", e);
        }
        return response;
    }

    @Transactional
    public void activityOrderStatusChange(String requestNo, AccountSendPrizeStatusEnum sendStatusEnum) {
        log.info("订单状态变更requestNo:{}", requestNo);
        ActivityOrder order = activityOrderMapper.selectByRequestNoForUpdate(requestNo);
        if (ActivityOrderSendStatusEnum.SEND_SUCCESS.getValue().equals(order.getSendStatus())) {
            throw new BizException("ACC10023");
        }
        ActivityOrder updateOrder = new ActivityOrder();
        updateOrder.setId(order.getId());
        updateOrder.setSendStatus(sendStatusEnum.getValue());
        updateOrder.setRequestNo(order.getRequestNo());
        activityOrderMapper.updateByPrimaryKeySelective(updateOrder);
    }

    /**
     * 按发送系统来源通知
     *
     * @param requestNo
     * @param sendStatusEnum
     */
    @Transactional
    public void asyncCall(String requestNo, AccountSendPrizeStatusEnum sendStatusEnum) {
        ActivityOrder activityOrder = activityOrderMapper.selectByRequestNoForUpdate(requestNo);
        if (AccountPrizeSourceFromEnum.ACTIVITY.getSourceFrom().equals(activityOrder.getSourceFrom())) {
            // 通知运营活动更新状态
            this.asyncCall(activityOrder, sendStatusEnum);
        } else if (AccountPrizeSourceFromEnum.SHENDUN2.getSourceFrom().equals(activityOrder.getSourceFrom())) {
            asyncCall4ReissueOrderAudit(activityOrder, sendStatusEnum);
        }

    }

    /**
     * 通知运营活动
     *
     * @param activityOrder
     * @param sendStatusEnum
     */
    private void asyncCall(ActivityOrder activityOrder, AccountSendPrizeStatusEnum sendStatusEnum) {
        log.info("通知运营活动更新状态:{},status:{}", activityOrder.getRequestNo(), sendStatusEnum.getDesc());
        ActivityNotifyRequestDTO requestDTO = new ActivityNotifyRequestDTO();
        requestDTO.setAccountNo(activityOrder.getAccountNo());
        requestDTO.setStatusEnum(SendPrizeStatusEnum.getStatusEnum(sendStatusEnum.getValue()));
        requestDTO.setSourceNo(activityOrder.getId());
        requestDTO.setUserId(activityOrder.getUserId());
        requestDTO.setRequestNo(activityOrder.getRequestNo());

        RpcContext.getContext().asyncCall(new Runnable() {
            @Override
            public void run() {
                activityNotifyDubboService.nodify(requestDTO);
            }
        });

    }


    private void asyncCall4ReissueOrderAudit(ActivityOrder activityOrder, AccountSendPrizeStatusEnum sendStatusEnum) {
        ReissueOrderAuditMqReqDTO mqReqDTO = new ReissueOrderAuditMqReqDTO();
        mqReqDTO.setId(activityOrder.getId());
        mqReqDTO.setAccountSendPrizeStatusEnumCode(sendStatusEnum.getValue());
        log.info("asyncCall4ReissueOrderAudit-线下还款发送消息-id:{},activityOrder:{}", activityOrder.getId(), JSONObject.toJSONString(activityOrder));
        //发送mq消息
        rabbitTemplate.convertAndSend(MQConstant.ReissueOrderAudit.EXCHANGE, MQConstant.ReissueOrderAudit.ROUTING, mqReqDTO);
    }

    /**
     * 成功处理
     * 1、查询营销账户基础表
     * 2、锁定营销账户
     * 3、更改订单发送状态
     * 4、查询用户账户信息
     * 5、添加账单
     * 6、财富中心统计
     *
     * @param requestNo
     * @param sendOrderDetailRespDTO
     */
    @Transactional
    public void successAsyncTransaction(String requestNo, SendOrderDetailRespDTO sendOrderDetailRespDTO) {
        log.info("现金红包发送成功:{}", requestNo);
        // 1、查询营销账户基础表
        AccountBase marketingAccountBase = accountService.loadAccountByAccountNo(PlateformAccountEnum.SYS_GENERATE_002.name());
        // 锁定SYS_GENERATE_002账户
        // 2、锁定营销账户
        AccountBase forUpdateMarketingAccountBase = accountBaseMapperExt.selectByPrimaryKeyForUpdate(marketingAccountBase.getId());

        ActivityOrder activityOrder = activityOrderMapper.selectByRequestNoForUpdate(requestNo);
        // 发送成功
        // 3、更改订单发送状态
        activityOrderStatusChange(activityOrder.getRequestNo(), AccountSendPrizeStatusEnum.SEND_SUCCESS);
        // 4、查询用户账户信息
        UserRoleEnum userRoleEnum = UserRoleEnum.enumOf(activityOrder.getAccountRole());
        AccountBase accountBase = accountService.loadAccountByAccountNo(activityOrder.getAccountNo());

        //AccountBase accountBase = accountService.getNiiwooAccount(activityOrder.getUserId(), userRoleEnum);

        // 5、添加账单
        addBill(activityOrder, forUpdateMarketingAccountBase.getId(), accountBase.getId(), sendOrderDetailRespDTO);

        // 6、财富中心统计
        countMontyTotal(activityOrder, accountBase, sendOrderDetailRespDTO);
    }

    /**
     * 统计财富中心，按红包类型划分统计类型
     * <p>
     * 投资奖励 105
     * 7投资理财金、8投资加息券、 9投资返现红包、
     * 平台奖励 104
     * 0 提现红包、4现金红包、5担保理财金、10担保返现红包、11借款返现红包 12借款利率折扣卡
     *
     * @param activityOrder
     * @param accountBase
     * @param sendOrderDetailRespDTO
     */
    public void countMontyTotal(ActivityOrder activityOrder, AccountBase accountBase, SendOrderDetailRespDTO sendOrderDetailRespDTO) {
        log.info("统计财富中心数据requestNo:{}", activityOrder.getRequestNo());
        if (!activityOrder.getSourceFrom().equals(AccountPrizeSourceFromEnum.ACTIVITY.getSourceFrom())) {
            log.info("非运营活动现金红包，不计入统计:{}", activityOrder.getRequestNo());
            return;
        }

        // 特殊处理：支付管理发送红包：USER_RED_RECHARGE 运营活动发送红包：USER_RED_CASH
        if (null != sendOrderDetailRespDTO.getFromTypeEnum() && UserPrizeFromTypeEnum.FROM_MANAGER.getType().equals(sendOrderDetailRespDTO.getFromTypeEnum().getType())) {
            log.info("支付管理发送的现金红包不统计到财富中心平台奖励:{}", activityOrder.getRequestNo());
            return;
        }

        AccountPrizeTypeIdEnum prizeTypeIdEnum = AccountPrizeTypeIdEnum.getPrizeTypeId(activityOrder.getPrizetypeid());
        if (prizeTypeIdEnum.getAmountType() == 0) {
            return;
        }

        MoneyTotalDTO moneyTotalDTO = new MoneyTotalDTO();
        moneyTotalDTO.setUserId(activityOrder.getUserId());
        moneyTotalDTO.setAccountId(accountBase.getId());

        AccountAmountTypeEnum accountAmountTypeEnum = AccountAmountTypeEnum.enumOf(prizeTypeIdEnum.getAmountType());
        moneyTotalDTO.setAmountType(accountAmountTypeEnum);
        moneyTotalDTO.setAmount(activityOrder.getAmount());
        // 统计
        moneyTotalLocalService.moneyTotal(moneyTotalDTO);
    }

    @Transactional
    public void failedAsyncTransaction(String requestNo) {
        log.info("现金红包发送失败:{}", requestNo);
        // 发送失败
        activityOrderStatusChange(requestNo, AccountSendPrizeStatusEnum.SEND_FAILED);
    }

    /**
     * 添加账单
     * 1、营销账户减钱
     * 2、用户账户加钱
     * 3、获取平台记账类型
     * 4、获取用户账单记账类型(特殊处理：支付管理发送红包：USER_RED_RECHARGE 运营活动发送红包：USER_RED_CASH)
     * 5、保存账单
     *
     * @param activityOrder          订单基础信息
     * @param fromAccountId          营销账户id
     * @param toAccountBaseId        用户账户id
     * @param sendOrderDetailRespDTO 红包属性参数
     */
    private void addBill(ActivityOrder activityOrder, Long fromAccountId, Long toAccountBaseId, SendOrderDetailRespDTO sendOrderDetailRespDTO) {
        log.info("现金红包发送成功开始添加账单----start-----");
        if (null == sendOrderDetailRespDTO) {
            sendOrderDetailRespDTO = new SendOrderDetailRespDTO();
        }
        // 3、获取平台记账类型
        AccountPrizeTypeIdEnum prizeTypeIdEnum = AccountPrizeTypeIdEnum.getPrizeTypeId(activityOrder.getPrizetypeid());
        BillSecondSubjectEnum fromBillSecondSubjectEnum = BillSecondSubjectEnum.getEnumByCode(prizeTypeIdEnum.getPlateformBillCode());
        AccountPrizeExtendTypeEnum extendTypeEnum = AccountPrizeExtendTypeEnum.getExtendTypeEnum(activityOrder.getExtendType());
        if (!activityOrder.getExtendType().equals(AccountPrizeExtendTypeEnum.DEFAULT.getExtendType())) {
            fromBillSecondSubjectEnum = BillSecondSubjectEnum.getEnumByCode(extendTypeEnum.getPlateformBillCode());
        }

        // 4、获取用户账单记账类型
        BillSecondSubjectEnum toBillSecondSubjectEnum = BillSecondSubjectEnum.getEnumByCode(prizeTypeIdEnum.getUserBillCode());
        // 特殊处理：支付管理发送红包：USER_RED_RECHARGE 运营活动发送红包：USER_RED_CASH
        if (null != sendOrderDetailRespDTO.getFromTypeEnum() && UserPrizeFromTypeEnum.FROM_MANAGER.getType().equals(sendOrderDetailRespDTO.getFromTypeEnum().getType())) {
            toBillSecondSubjectEnum = BillSecondSubjectEnum.getEnumByCode(BillSecondSubjectEnum.USER_RED_RECHARGE.getCode());
        }
        if (!activityOrder.getExtendType().equals(AccountPrizeExtendTypeEnum.DEFAULT.getExtendType())) {
            toBillSecondSubjectEnum = BillSecondSubjectEnum.getEnumByCode(extendTypeEnum.getUserBillCode());
        }

        //用户(变更余额 + 记账)
        AddBillDetailDTO addBillDetailDTO = new AddBillDetailDTO();
        addBillDetailDTO.setAmount(activityOrder.getAmount());
        addBillDetailDTO.setBillSecondSubjectEnum(toBillSecondSubjectEnum);
        addBillDetailDTO.setRemark2(sendOrderDetailRespDTO.getRemark());

        AddBillAndChangeBalanceDTO billDTO = new AddBillAndChangeBalanceDTO();
        billDTO.setAccountId(toAccountBaseId);
        billDTO.setAmount(activityOrder.getAmount());
        billDTO.setInoutType(InoutTypeEnum.IN_TYPE);
        billDTO.setOrderId(activityOrder.getId());
        billDTO.setOrderType(OrderTypeEnum.ACTIVITY);
        billDTO.setRequestNo(activityOrder.getRequestNo());
        billDTO.setStatus(BillStatusEnum.SUCCESS);
        billDTO.setChannelCode(ChannelCodeEnum.APP);
        billDTO.setRelationUserId(PlatformConstant.PLATFORM_USER_ID);
        billDTO.setRelationAccountId(fromAccountId);
        billDTO.setInvestId(sendOrderDetailRespDTO.getInvestId());
        
        // 普通标（信用卡贷、社保贷、抵押贷等）
		if (SendPrizeDetailProjectTypeEnum.NORMAL.getProjectType().equals(sendOrderDetailRespDTO.getProjectType())
				&& Objects.nonNull(sendOrderDetailRespDTO.getProjectId())) {
			billDTO.setProjectId(sendOrderDetailRespDTO.getProjectId());
			ProjectDTO projectDTO = projectDubboService.selectProjectById(sendOrderDetailRespDTO.getProjectId());
			if (Objects.nonNull(projectDTO)) {
				billDTO.setProjectType(BorrowProjectTypeEnum.enumOf(projectDTO.getType()));
				billDTO.setProjectTitle(projectDTO.getTitle());
			}
		}
		// 智能投
		else if (SendPrizeDetailProjectTypeEnum.INTELLIGENCE.getProjectType().equals(sendOrderDetailRespDTO.getProjectType())) {
			billDTO.setProjectPackageId(sendOrderDetailRespDTO.getProjectId());
		}
        billDTO.setAddBillDetailDTOList(Arrays.asList(addBillDetailDTO));
        billFacade.addBillAndChangeBalance(billDTO);

        //平台(变更余额 + 记账)
        addBillDetailDTO = new AddBillDetailDTO();
        addBillDetailDTO.setAmount(activityOrder.getAmount());
        addBillDetailDTO.setBillSecondSubjectEnum(fromBillSecondSubjectEnum);
        addBillDetailDTO.setRemark2(sendOrderDetailRespDTO.getRemark());

        billDTO = new AddBillAndChangeBalanceDTO();
        billDTO.setAccountId(fromAccountId);
        billDTO.setAmount(activityOrder.getAmount());
        billDTO.setInoutType(InoutTypeEnum.OUT_TYPE);
        billDTO.setOrderId(activityOrder.getId());
        billDTO.setOrderType(OrderTypeEnum.ACTIVITY);
        billDTO.setRequestNo(activityOrder.getRequestNo());
        billDTO.setStatus(BillStatusEnum.SUCCESS);
        billDTO.setChannelCode(ChannelCodeEnum.APP);
        billDTO.setRelationUserId(activityOrder.getUserId());
        billDTO.setRelationAccountId(toAccountBaseId);
        billDTO.setInvestId(sendOrderDetailRespDTO.getInvestId());
        // 普通标（信用卡贷、社保贷、抵押贷等）
		if (SendPrizeDetailProjectTypeEnum.NORMAL.getProjectType().equals(sendOrderDetailRespDTO.getProjectType())
				&& Objects.nonNull(sendOrderDetailRespDTO.getProjectId())) {
			billDTO.setProjectId(sendOrderDetailRespDTO.getProjectId());
			ProjectDTO projectDTO = projectDubboService.selectProjectById(sendOrderDetailRespDTO.getProjectId());
			if (Objects.nonNull(projectDTO)) {
				billDTO.setProjectType(BorrowProjectTypeEnum.enumOf(projectDTO.getType()));
				billDTO.setProjectTitle(projectDTO.getTitle());
			}
		}
		// 智能投
		else if (SendPrizeDetailProjectTypeEnum.INTELLIGENCE.getProjectType().equals(sendOrderDetailRespDTO.getProjectType())) {
			billDTO.setProjectPackageId(sendOrderDetailRespDTO.getProjectId());
		}
        billDTO.setAddBillDetailDTOList(Arrays.asList(addBillDetailDTO));
        billFacade.addBillAndChangeBalance(billDTO);

        log.info("现金红包发送成功开始添加账单----end-----");
    }

    /**
     * 计划任务补发未发送成功的订单
     * 1、查询minute内未发送的订单
     * 2、根据查询结果，业务成功、失败更新订单状态，如未查询到订单记录而重新补发
     */
    public void resendPrize() {
        log.info("开始补偿查询红包发送信息----start--------");
        Integer minute = 30;
        // 查询半个小时内未发送的订单
        List<ActivityOrder> orderList = activityOrderMapper.getNotSendSuccessList(minute, AccountSendPrizeStatusEnum.NOT_SEND.getValue());
        if (null == orderList || orderList.isEmpty()) {
            return;
        }
        for (ActivityOrder order : orderList) {
            try {
                QueryTransactionRequest queryTransactionRequest = new QueryTransactionRequest();
                queryTransactionRequest.setTransactionType(TradeQueryTypeEnum.TRANSACTION);
                queryTransactionRequest.setRequestNo(order.getRequestNo());
                QueryTransactionResponse response = lanMaoDirectService.queryTransaction(queryTransactionRequest).get();
                log.info("查询resendPrize发送订单{}结果:{}", order.getRequestNo(), JSON.toJSONString(response));
                if (response == null) {
                    continue;
                }

                if (resendAsyncSendTransaction(response, order)) {
                    continue;
                }

                // 查询对象不存在
                if (!LanMaoErrorCodeEnum.QUERY_OBJECT_NOT_EXIST.getCode().equals(response.getErrorCode())) {
                    log.info("查询resendPrize{}成功,ErrorCode返回:{}", order.getRequestNo(), response.getErrorCode());
                    continue;
                }

                UserRoleEnum userRoleEnum = UserRoleEnum.enumOf(order.getAccountRole());
                log.info("查询resendPrize{}成功,订单信息不存在重新发送", order.getRequestNo());
                // 业务失败
                boolean asyncFlag = asyncSendTransaction(order.getRequestNo(), userRoleEnum);
                AccountSendPrizeStatusEnum sendPrizeStatusEnum = asyncFlag ? AccountSendPrizeStatusEnum.SEND : AccountSendPrizeStatusEnum.SEND_FAILED;
                getSlefProxy().activityOrderStatusChange(order.getRequestNo(), sendPrizeStatusEnum);

                if (AccountPrizeSourceFromEnum.ACTIVITY.getSourceFrom().equals(order.getSourceFrom())) {
                    getSlefProxy().asyncCall(order.getRequestNo(), sendPrizeStatusEnum);
                }
            } catch (Exception e) {
                log.error("补发红包调用异常:", e);
            }
        }
        log.info("开始补偿查询红包发送信息----end--------");
    }

    /**
     * 计划任务查询发送成功但未返回的订单
     * 1、查询minute内发送成功未返回的订单
     * 2、根据查询结果，业务成功、失败更新订单状态
     */
    public void queryTransactionPrize() {
        log.info("计划任务查询发送成功但未返回的订单----start--------");
        Integer minute = 30;
        // 查询半个小时内未发送的订单
        List<ActivityOrder> orderList = activityOrderMapper.getNotSendSuccessList(minute, AccountSendPrizeStatusEnum.SEND.getValue());
        if (null == orderList || orderList.isEmpty()) {
            return;
        }
        for (ActivityOrder order : orderList) {
            try {
                QueryTransactionRequest queryTransactionRequest = new QueryTransactionRequest();
                queryTransactionRequest.setTransactionType(TradeQueryTypeEnum.TRANSACTION);
                queryTransactionRequest.setRequestNo(order.getRequestNo());
                QueryTransactionResponse response = lanMaoDirectService.queryTransaction(queryTransactionRequest).get();
                log.info("查询queryTransactionPrize发送订单{}结果:{}", order.getRequestNo(), JSON.toJSONString(response));
                if (response == null) {
                    continue;
                }

                if (resendAsyncSendTransaction(response, order)) {
                    continue;
                }
            } catch (Exception e) {
                log.error("计划任务查询queryTransactionPrize发送成功但未返回的订单调用异常:", e);
            }
        }
        log.info("计划任务查询queryTransactionPrize发送成功但未返回的订单----end--------");
    }

    /**
     * 查询业务状态判断
     *
     * @param response
     * @param order
     * @return
     */
    private boolean resendAsyncSendTransaction(QueryTransactionResponse response, ActivityOrder order) {
        if (ResponseStatusEnum.SUCCESS.name().equals(response.getStatus())
                && StringUtils.isAllEmpty(response.getErrorCode(), response.getErrorMessage())
                && !CollectionUtils.isEmpty(response.getRecords())) {
            // 业务处理成功
            boolean successFlag = TransationStatusEnum.SUCCESS.name().equals(response.getRecords().get(0).getStatus());
            // 业务处理失败
            boolean failFlag = TransationStatusEnum.FAIL.name().equals(response.getRecords().get(0).getStatus());
            AccountSendPrizeStatusEnum sendPrizeStatusEnum = null;
            if (successFlag) {
                log.info("业务处理成功requestNo：{}", order.getRequestNo());
                sendPrizeStatusEnum = AccountSendPrizeStatusEnum.SEND_SUCCESS;
                SendOrderDetailRespDTO sendOrderDetailRespDTO = getPrizeDescription(order.getRequestNo());
                // 发送成功账单记录
                getSlefProxy().successAsyncTransaction(order.getRequestNo(), sendOrderDetailRespDTO);
            } else if (failFlag) {
                log.info("业务处理失败requestNo：{}", order.getRequestNo());
                sendPrizeStatusEnum = AccountSendPrizeStatusEnum.SEND_FAILED;
                getSlefProxy().activityOrderStatusChange(order.getRequestNo(), sendPrizeStatusEnum);
            } else {
                return false;
            }
            if (null != sendPrizeStatusEnum) {
                // 业务成功
                getSlefProxy().asyncCall(order.getRequestNo(), sendPrizeStatusEnum);
                log.info("查询{}成功,业务状态返回:{}", order.getRequestNo(), sendPrizeStatusEnum.getValue());
            }
            return true;
        } else {
            return false;
        }
    }

    /**
     * 按orderId查询，不推荐，因分表原因，会多次查询
     *
     * @param orderNo
     * @return
     */
    public ActivityOrderRespDTO querySendCashPrizeInfo(Long orderNo) {
        ActivityOrder order = activityOrderMapper.selectByPrimaryKey(orderNo);
        if (null == order) {
            return null;
        }
        ActivityOrderRespDTO respDTO = new ActivityOrderRespDTO();
        respDTO.setId(order.getId());
        respDTO.setRequestNo(order.getRequestNo());
        respDTO.setUserId(order.getUserId());
        respDTO.setAccountRole(order.getAccountRole());
        respDTO.setAccountNo(order.getAccountNo());
        respDTO.setPrizetypeid(order.getPrizetypeid());
        respDTO.setExtendType(order.getExtendType());
        respDTO.setSourceFrom(order.getSourceFrom());
        respDTO.setAmount(order.getAmount());
        respDTO.setSendStatus(order.getSendStatus());
        respDTO.setBatchOrderNo(order.getBatchOrderNo());
        respDTO.setCreateDate(order.getCreateDate());
        respDTO.setUpdateDate(order.getUpdateDate());
        return respDTO;
    }

    /**
     * 获取红包描述信息
     *
     * @param requestNo
     * @return
     */
    public SendOrderDetailRespDTO getPrizeDescription(String requestNo) {
        ActivityOrder activityOrder = getSlefProxy().getActivityOrderByRequestNo(requestNo);
        SendOrderDetailRespDTO responseDTO = null;
        if (AccountPrizeSourceFromEnum.ACTIVITY.getSourceFrom().equals(activityOrder.getSourceFrom())) {
            responseDTO = activityPrizeDubboService.getSendPrizeDetailByParams(activityOrder.getUserId(), activityOrder.getRequestNo());
        }
        return responseDTO;
    }

    private static MarketingLocalService getSlefProxy() {
        return (MarketingLocalService) AopContext.currentProxy();
    }

}
